home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1997 September
/
Macworld (1997-09).dmg
/
Shareware World
/
Utilities
/
Text Processing
/
Alpha
/
Tcl
/
Modes
/
shellMode.tcl
< prev
next >
Wrap
Text File
|
1997-05-29
|
14KB
|
536 lines
################################################################################
# Shell routines.
################################################################################
if $startingUp {
addMode Shel dummyShel {"*tcl\ sh*"} { tclMenu }
newModeVar Shel wordBreak {(\$)?[a-zA-Z0-9_.]+} 0
newModeVar Shel wordWrap {0} 1
newModeVar Shel wordBreakPreface {[^a-zA-Z0-9_\$]} 0
newModeVar Shel autoMark 0 1
regModeKeywords -m {«} Shel {}
return
}
set otherDirs {}
proc pushd {args} {
global otherDirs
if {[string length $args]} {
set otherDirs [cons [pwd] $otherDirs]
cd [string trim [eval list $args] " \{\}"]
} else {
if {[llength $otherDirs]} {
set n [car $otherDirs]
set otherDirs [cons [pwd] [cdr $otherDirs]]
cd $n
} else {
return "No other directories"
}
}
}
proc pd {args} {
if {[string length $args]} {
eval pushd $args
} else {
pushd
}
}
proc dirs {} {global otherDirs; cons [pwd] $otherDirs}
proc popd {} {
global otherDirs
if {[llength $otherDirs]} {
cd [car $otherDirs]
set otherDirs [cdr $otherDirs]
} else {
return "No other directories"
}
}
proc folder {} {
switchTo Finder
openFolder [pwd]
}
proc setShellMode {} {
setTclMode
changeMode "Shel"
insertMenu "Tcl"
}
proc initShell {} {
insertText "Welcome to Alpha's Tcl shell."
insertText -w [lindex [winNames] 0] [shellPrompt]
}
# Return the prompt. We want the window name because some of the commands
# we evaluate (such as 'edit') open a new window, and we want the insertion
# to be done in the shell window.
proc shellPrompt {} {
return "\r«[file tail [string trimright [pwd] {:}]]» "
}
proc shellCarriageReturn {} {
global mode histnum
global _text
global _returnText
set pos [getPos]
if {![catch {regexp {∞} [getText $pos [nextLineStart $pos]]} res] && $res} {
gotoMatch; return;
}
set ind [string first "»" [getText [lineStart $pos] $pos]]
if {$ind < 0} {
carriageReturn
return
}
set lStart [expr [lineStart $pos]+$ind+2]
endOfLine
set _text [getText $lStart [getPos]]
set fileName [lindex [winNames] 0]
if {[getPos] != [maxPos]} {
goto [maxPos]
insertText -w $fileName $_text
}
if {[string first "Toolserver" $fileName] != -1} {
if {![catch {dosc -n ToolServer -s $_text} _returnText]} {
insertText "\r" $_returnText
} else {
insertText "\r"
}
mpwPrompt
} elseif {$fileName == "* Comet Server *"} {
cometSendAndPrompt $_text
} else {
uplevel #0 {catch $_text _returnText}
history add $_text
if {[string length $_returnText]} {
insertText -w $fileName "\r" $_returnText [shellPrompt]
} else {
insertText -w $fileName [shellPrompt]
}
set histnum [history nextid]
}
unset _text
unset _returnText
}
bind '\r' carriageReturn
bind '\r' shellCarriageReturn "Shel"
bind '\r' shellCarriageReturn "MPW"
bind up <z> prevHist Shel
bind down <z> nextHist Shel
proc prevHist {} {
global histnum
set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
if {[set ind [string first "» " $text]] > 0} {
goto [expr [lineStart [getPos]] + $ind + 2]
} else return
incr histnum -1
if {[catch {history event $histnum} text]} {
incr histnum
endOfLine
return
}
set to [nextLineStart [getPos]]
if {[lookAt [expr $to-1]] == "\r"} {incr to -1}
replaceText [getPos] $to $text
}
proc nextHist {} {
global histnum
set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
if {[set ind [string first "» " $text]] > 0} {
goto [expr [lineStart [getPos]] + $ind + 2]
} else return
incr histnum
if {[catch {history event $histnum} text]} {
incr histnum -1
endOfLine
return
}
set to [nextLineStart [getPos]]
if {[lookAt [expr $to-1]] == "\r"} {incr to -1}
replaceText [getPos] $to $text
}
proc startMPW {} {
global toolserverPath
if {![string length [checkRunning ToolServer MPSX toolserverPath]]} return
insertText "Welcome to Alpha's MPW shell (using ToolServer via AppleEvents)."
bind '\r' shellCarriageReturn "MPW"
carriageReturn
mpwPrompt
}
proc mpwPrompt {} {
insertText "«mpw» "
}
proc setMPWMode {} {
changeMode "MPW"
}
# shellCarriageReturn
#=============================================================================
# Shell Aliases
#=============================================================================
proc l {args} {
eval [concat "ls -CF" $args]}
proc ll {args} {
eval [concat "ls -l" $args]}
proc wc {args} {
set res {}
set totChars 0
set totLines 0
set totWords 0
set args [glob -nocomplain $args]
foreach file $args {
set id [open $file]
set chars [string length [set text [read $id]]]
set lines [llength [split $text "\n"]]
set words [llength [split $text]]
append res [format "\r%8d%8d%8d $file" $lines $words $chars]
set totChars [expr $totChars+$chars]
set totWords [expr $totWords+$words]
set totLines [expr $totLines+$lines]
close $id
}
if {[llength $args] > 1} {
append res [format "\r%8d%8d%8d total" $totLines $totWords $totChars]
}
return [string range $res 1 end]
}
#================================================================================
proc tclFileCompletion {} {
set silly "*"
set pos [getPos]
set res [search -f 0 -i 0 -m 0 -r 1 -n {["\{ \t\r]} [expr $pos - 1]]
if {[string length $res]} {
set from [lindex $res 1]
if {$from < $pos} {
set pd [pwd]
set text [getText $from $pos]
if {[string index $text 0] == ":"} {
set pd [string trimright $pd ":"]
}
if {[catch {glob $pd$text$silly} globbed]} {
set globbed [glob $text$silly]
set pd ""
}
if {[llength $globbed] == 1} {
set len [string length $pd$text]
insertText [string range [lindex $globbed 0] $len end]
} elseif {[llength $globbed] != 0} {
set globbed [lsort $globbed]
set one [lindex $globbed 0]
set two [lindex $globbed end]
set len [string length $pd$text]
set one [string range $one $len end]
set two [string range $two $len end]
set elen [string length $one]
if {[string length $two] < $elen} {
set elen [string length $two]
}
set len 0
set str ""
while {($len < $elen) && ([string match $str[string index $one $len]$silly $two])} {
append str [string index $one $len]
incr len
}
if {!$len} {
set elen [string length $pd]
foreach g $globbed {
lappend short [string range $g $elen end]
}
set blah [getText [lineStart [getPos]] [getPos]]
insertText "\r" $short "\r" $blah
} else {
insertText $str
}
}
}
}
}
#================================================================================
# To prevent ambiguity, 'from' is assumed to be a complete pathname, ending
# in a directory name. If it doesn't end w/ a colon, one is added. 'to' is
# assumed to be the parent directory of the top directory we are creating.
#================================================================================
proc cpdir {from to} {
set cwd [pwd]
if {[string match ":*" $from] || [string match ":*" $to] ||
![file exists $from] || ![file exists $to]} {
error "'cpdir' args must be complete pathnames of existing folders."
}
if {![string match "*:" $from]} {append from ":"}
if {![string match "*:" $to]} {append to ":"}
if {![file isdir $from] || ![file isdir $to]} {
exit 1
}
set res [catch {cphier $from $to} val]
cd $cwd
if {$res} {error $val}
}
proc cphier {from to} {
set savedir [pwd]
if {[string index $from [expr [string len $from] - 1]] != ":"} {append from ":"}
set dir [file tail [string trimright $from ":"]]
cd $to
mkdir "$dir"
foreach f [glob "$from*"] {
if {[file isdir $f]} {
cphier "$f:" "$to$dir:"
} else {
cp $f $to$dir:
}
}
cd $savedir
}
proc shellBol {} {
set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
if {[set ind [string first "» " $text]] > 0} {
goto [expr [lineStart [getPos]] + $ind + 2]
} else {
goto [lineStart [getPos]]
}
}
bind 'a' <z> shellBol Shel
proc dummyShel {} {dummyTcl}
#================================================================================
proc shellup {} {
set pos [expr [lineStart [getPos]] - 1]
if {[catch {regexp {∞} [getText [lineStart $pos] [nextLineStart $pos]]} res] || !$res} {
previousLine; return
}
select [lineStart $pos] [nextLineStart $pos]
}
bind up shellup Shel
proc shelldown {} {
set pos [nextLineStart [getPos]]
if {[catch {regexp {∞} [getText $pos [nextLineStart $pos]]} res] || !$res} {
nextLine; return
}
select $pos [nextLineStart $pos]
}
bind down shelldown Shel
#================================================================================
#####
# (Usage: 'lt' sorts by time, like UNIX's 'ls -lt'.
# 'lt -t' sorts by filename, like UNIX's 'ls -l'.
# Optionally a directory name can be added as an argument.)
proc sortdt {dt} {
scan $dt "%d/%d/%d {%d:%d:%d %1sM}" mon day yea hou min sec z
if {$z == "P"} {incr hou 12}
if {[string length $yea] == 1} {
set year 200$yea
} elseif {$yea > 40} {
set year 19$yea
} else {
set year 20$yea
}
return [format "%04d%02d%02d%02d%02d" $year $mon $day $hou $min]
}
proc lth args {
global mode
set val "*"
set sort 1
scan [lindex [mtime [now]] 0] "%d/%d/%d" one two three
if {[string length $three] == 1} {
set year 200$three
} elseif {$three > 40} {
set year 19$three
} else {
set year 20$three
}
foreach arg $args {
switch -- $arg {
"-t" {set sort 0}
default {set val $arg}
}
}
set mod ""
foreach f [eval glob $val] {
if {[catch {getFileInfo $f info}]} {
if {$sort} {set mod "000000000000 "}
lappend text [format "%s%s %8d%8d %6s %5s %4s %s %s\n" $mod "D" "0" "0" "" "" "" "DIR " [file tail $f]]
continue
}
if {$sort} {set mod "[sortdt [mtime $info(modified) s]] "}
set m [mtime $info(modified) a]
set zer [lindex $m 0]
set dat [format "%s %2s" [lindex $zer 1] [string trimright [lindex $zer 2] {,}]]
if {[lindex $zer 3] == $year} {
if {[scan [lindex $m 1] "%d:%d:%d %s" one two three am] != 4} {
error "Didn't get four from scan"
}
if {[string length $two] == 1} {set two "0$two"}
set tm [expr {$am == "AM"} ? $one : [expr $one + 12]]:$two
} else {
set tm " [lindex $zer 3]"
}
lappend text [format "%sF %8d%8d %s %5s %s %s %s\n" $mod $info(datalen) $info(resourcelen) $dat $tm $info(type) $info(creator) [file tail $f]]
}
if {$sort} {
foreach ln [lsort -de $text] {
append txt [string range $ln 13 end]
}
set ans [string trimright $txt]
} else {
set ans [string trimright [join $text {}]]
}
if { $mode=="Shel" } { return $ans } else {
new
insertText $ans "\r"
catch shrinkHeight
setWinInfo dirty 0
setWinInfo read-only 1
}
}
#================================================================================
proc ps {} {
foreach p [processes] {
append text [format "%-25s %4s %10d %10d\r" [lindex $p 0] [lindex $p 1] [lindex $p 2] [lindex $p 3]]
}
return [string trimright $text]
}
#================================================================================
# Recursively make creator of all text files 'ALFA'. Optionally takes a starting
# dir argument, otherwise starts in current directory. Auto-Doubled are no
# longer recognized by auto-doubler! Why? Some sort of conflict w/ 'PBSetFInfo'.
proc creator {{dir ":"}} {
if {![catch {glob -t TEXT $dir*} files]} {
foreach f $files {
message $f
setFileInfo $f creator ALFA
}
}
if {![catch {glob $dir*} dirs]} {
foreach d $dirs {
if {[file isdir $d]} {creator $d:}
}
}
}
#===============================================================================
proc ShelDblClick {args} { eval TclDblClick $args }
#===============================================================================
proc tomac args {
set files {}
foreach arg $args {
append files " " [glob $arg]
}
set dir [pwd]
foreach f $files {
message "$f..."
set fd [open $dir$f "r"]
set text [read $fd]
close $fd
regsub "\n" $text "\r" text
set fd [open "$dir$f" "w"]
puts -nonewline $fd $text
close $fd
}
message ""
}
#===============================================================================
proc unixToMac {fname} {
set fd [open $fname]
set text [read $fd]
close $fd
set fd [open $fname "w"]
puts -nonewline $fd $text
close $fd
}
proc setCreator args {
set files {}
set creator [car $args]
foreach arg [cdr $args] {
append files " " [glob $arg]
}
foreach f $files {
setFileInfo $f creator $creator
}
}
proc setType args {
set files {}
set type [car $args]
foreach arg [cdr $args] {
append files " " [glob $arg]
}
foreach f $files {
setFileInfo $f type $type
}
}
#===============================================================================